/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Codec
 * @{
 *
 * @brief Codec模块接口定义
 *
 * Codec模块涉及自定义类型、音视频编解码组件初始化、参数设置、数据的轮转和控制等。
 *
 * @since 3.1
 */

/**
 * @file codec_component_type.h
 *
 * @brief Codec模块接口定义中使用的自定义数据类型
 *
 * Codec模块接口定义中使用的自定义数据类型, 包括编解码类型、音视频参数、buffer定义等。
 *
 * @since 3.1
 */

#ifndef CODEC_COMPONENT_TYPE_H
#define CODEC_COMPONENT_TYPE_H

#include <stdint.h>
#include <stdbool.h>
#include "OMX_Types.h"
#include "OMX_Index.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

/**
 * @brief 采样格式最大值
 */
#define SAMPLE_FMT_NUM 32

/**
 * @brief 枚举编解码的类型
 */
typedef enum {
    /** 视频解码类型 */
    VIDEO_DECODER,
    /** 视频编码类型 */
    VIDEO_ENCODER,
    /** 音频解码类型 */
    AUDIO_DECODER,
    /** 音频编码类型 */
    AUDIO_ENCODER,
    /** 无效类型 */
    INVALID_TYPE
} CodecType;

/**
 * @brief 枚举音视频编解码组件类型
 */
typedef enum {
    /** 图像 JPEG 媒体类型 */
    MEDIA_ROLETYPE_IMAGE_JPEG = 0,
    /** 视频 H.264 媒体类型 */
    MEDIA_ROLETYPE_VIDEO_AVC,
    /** 视频 H.265 媒体类型 */
    MEDIA_ROLETYPE_VIDEO_HEVC,
    /** 音频编解码器类型 */
    MEDIA_ROLETYPE_AUDIO_FIRST = 0x10000,
    /** 音频 AAC 媒体类型 */
    MEDIA_ROLETYPE_AUDIO_AAC = 0x10000,
    /** 音频 G711A 媒体类型 */
    MEDIA_ROLETYPE_AUDIO_G711A,
    /** 音频 G711U 媒体类型 */
    MEDIA_ROLETYPE_AUDIO_G711U,
    /** 音频 G726 媒体类型 */
    MEDIA_ROLETYPE_AUDIO_G726,
    /** 音频 PCM 媒体类型 */
    MEDIA_ROLETYPE_AUDIO_PCM,
    /** 音频 MP3 媒体类型 */
    MEDIA_ROLETYPE_AUDIO_MP3,
    /** 无效媒体类型 */
    MEDIA_ROLETYPE_INVALID,
} AvCodecRole;

/**
 * @brief 枚举Codec profiles.
 */
typedef enum {
    /** 无效的 profile */
    INVALID_PROFILE = 0,
    /** AAC-Low Complex */
    AAC_LC_PROFILE = 0x1000,
    /** AAC-Main */
    AAC_MAIN_PROFILE,
    /** HEAAC, AAC+, or AACPlusV1 */
    AAC_HE_V1_PROFILE,
    /** AAC++ or AACPlusV2 */
    AAC_HE_V2_PROFILE,
    /** AAC-Low Delay */
    AAC_LD_PROFILE,
    /** AAC-Enhanced Low Delay */
    AAC_ELD_PROFILE,
    /** H.264 Baseline */
    AVC_BASELINE_PROFILE = 0x2000,
    /** H.264 Main */
    AVC_MAIN_PROFILE,
    /** H.264 High */
    AVC_HIGH_PROFILE,
    /** H.265 Main */
    HEVC_MAIN_PROFILE = 0x3000,
    /** H.265 Main 10 */
    HEVC_MAIN_10_PROFILE,
} Profile;

/**
* @brief 对齐结构定义, 包含宽高的对齐
 */
typedef struct {
    int32_t widthAlignment;  /** 宽的对齐值 */
    int32_t heightAlignment; /** 高的对齐值 */
} Alignment;

/**
 * @brief 矩形的定义
 */
typedef struct {
    int32_t width;  /** 矩形的宽 */
    int32_t height; /** 矩形的高 */
} Rect;

/**
 * @brief 取值范围的定义
 */
typedef struct {
    int32_t min; /** 最小值 */
    int32_t max; /** 最大值 */
} RangeValue;

/**
 * @brief 枚举播放能力
 */
typedef enum {
    /** 自适应播放 */
    CODEC_CAP_ADAPTIVE_PLAYBACK = 0x1,
    /** 安全播放 */
    CODEC_CAP_SECURE_PLAYBACK = 0x2,
    /** 通道播放 */
    CODEC_CAP_TUNNEL_PLAYBACK = 0x4,
    /** 视频图像平面/音频通道平面 */
    CODEC_CAP_MULTI_PLANE = 0x10000,
} CodecCapsMask;

/**
 * @brief 枚举音频采样率
 */
typedef enum {
    /** 8K采样率 */
    AUD_SAMPLE_RATE_8000   = 8000,
    /** 12K采样率 */
    AUD_SAMPLE_RATE_12000  = 12000,
    /** 11.025K采样率 */
    AUD_SAMPLE_RATE_11025  = 11025,
    /** 16K采样率 */
    AUD_SAMPLE_RATE_16000  = 16000,
    /** 22.050K采样率 */
    AUD_SAMPLE_RATE_22050  = 22050,
    /** 24K采样率 */
    AUD_SAMPLE_RATE_24000  = 24000,
    /** 32K采样率 */
    AUD_SAMPLE_RATE_32000  = 32000,
    /** 44.1K采样率 */
    AUD_SAMPLE_RATE_44100  = 44100,
    /** 48K采样率 */
    AUD_SAMPLE_RATE_48000  = 48000,
    /** 64K采样率 */
    AUD_SAMPLE_RATE_64000  = 64000,
    /** 96K采样率 */
    AUD_SAMPLE_RATE_96000  = 96000,
    /** 无效采样率 */
    AUD_SAMPLE_RATE_INVALID,
} AudioSampleRate;

/**
 * @brief 枚举音频采样格式
 *
 * 对于planar的采样格式, 每个声道的数据是独立存储在data中;
 * 对于packed的采样格式, 只使用第一个data, 每个声道的数据是交错存储的。
 */
typedef enum {
    /** Unsigned 8 bits, packed */
    AUDIO_SAMPLE_FMT_U8,
    /** Signed 16 bits, packed */
    AUDIO_SAMPLE_FMT_S16,
    /** Signed 32 bits, packed */
    AUDIO_SAMPLE_FMT_S32,
    /** Float, packed */
    AUDIO_SAMPLE_FMT_FLOAT,
    /** Double, packed */
    AUDIO_SAMPLE_FMT_DOUBLE,
    /** Unsigned 8 bits, planar */
    AUDIO_SAMPLE_FMT_U8P,
    /** Signed 16 bits, planar */
    AUDIO_SAMPLE_FMT_S16P,
    /** Signed 32 bits, planar */
    AUDIO_SAMPLE_FMT_S32P,
    /** Float, planar */
    AUDIO_SAMPLE_FMT_FLOATP,
    /** Double, planar */
    AUDIO_SAMPLE_FMT_DOUBLEP,
    /** Invalid sampling format */
    AUDIO_SAMPLE_FMT_INVALID,
} AudioSampleFormat;

/**
 * @brief 定义视频编解码能力
 */
#define PIX_FORMAT_NUM 16 /** 支持的像素格式数组大小 */
typedef struct {
    Rect minSize;                            /** 支持的最小分辨率 */
    Rect maxSize;                            /** 支持的最大分辨率 */
    Alignment whAlignment;                   /** 宽高对齐值 */
    RangeValue blockCount;                   /** 支持的块数量范围 */
    RangeValue blocksPerSecond;              /** 每秒可处理的块数量范围 */
    Rect blockSize;                          /** 支持的块大小 */
    int32_t supportPixFmts[PIX_FORMAT_NUM];  /** 支持的像素格式, 详见{@link OMX_COLOR_FORMATTYPE} */
} VideoPortCap;

/**
 * @brief 定义音频编解码能力
 */
#define SAMPLE_FORMAT_NUM 12 /** 支持的音频采样格式数组大小 */
#define SAMPLE_RATE_NUM 16 /** 支持的音频采样率数组大小 */
#define CHANNEL_NUM 16 /** 支持的音频通道数组大小 */
typedef struct {
    int32_t sampleFormats[SAMPLE_FMT_NUM]; /** 支持的音频采样格式, 详见{@link AudioSampleFormat} */
    int32_t sampleRate[SAMPLE_RATE_NUM];   /** 支持的音频采样率, 详见{@link AudioSampleRate} */
    int32_t channelLayouts[CHANNEL_NUM];   /** 支持的音频通道数channel layouts */
    int32_t channelCount[CHANNEL_NUM];     /** 支持的音频通道数*/
} AudioPortCap;

/**
 * @brief 定义音视频编解码能力
 */
typedef union {
    VideoPortCap video;               /** 视频编解码能力 */
    AudioPortCap audio;               /** 音频编解码能力 */
} PortCap;

/**
 * @brief 枚举编解码处理模式
 */
typedef enum {
    /** 同步模式输入buffer */
    PROCESS_BLOCKING_INPUT_BUFFER     = 0X1,
    /** 同步模式输出buffer */
    PROCESS_BLOCKING_OUTPUT_BUFFER    = 0X2,
    /** 同步模式控制流 */
    PROCESS_BLOCKING_CONTROL_FLOW     = 0X4,
    /** 异步模式输入buffer */
    PROCESS_NONBLOCKING_INPUT_BUFFER  = 0X100,
    /** 异步模式输出buffer */
    PROCESS_NONBLOCKING_OUTPUT_BUFFER = 0X200,
    /** 异步模式控制流 */
    PROCESS_NONBLOCKING_CONTROL_FLOW  = 0X400,
} CodecProcessMode;

/**
 * @brief 定义Codec编解码能力
 */
#define NAME_LENGTH 32  /** 组件名称大小 */
#define PROFILE_NUM 256  /** 支持的profile数组大小 */
typedef struct {
    AvCodecRole role;                     /** 媒体类型 */
    CodecType type;                       /** 编解码类型 */
    char compName[NAME_LENGTH];           /** 编解码组件名称 */
    int32_t supportProfiles[PROFILE_NUM]; /** 支持的profiles, 详见{@link Profile} */
    int32_t maxInst;                      /** 最大实例 */
    bool isSoftwareCodec;                 /** 软件编解码还是硬件编解码 */
    int32_t processModeMask;              /** 编解码处理模式掩码, 详见{@link CodecProcessMode}. */
    uint32_t capsMask;                    /** 编解码播放能力掩码, 详见{@link CodecCapsMask}. */
    RangeValue bitRate;                   /** 支持的码率范围 */
    PortCap port;                         /** 支持的音视频编解码能力 */
} CodecCompCapability;

/**
 * @brief 定义buffer类型
 */
enum BufferType {
    /** 无效buffer类型 */
    BUFFER_TYPE_INVALID = 0,
    /** 虚拟地址类型 */
    BUFFER_TYPE_VIRTUAL_ADDR = 0x1,
    /** 共享内存类型 */
    BUFFER_TYPE_AVSHARE_MEM_FD = 0x2,
    /** handle类型 */
    BUFFER_TYPE_HANDLE = 0x4,
    /** 动态handle类型 */
    BUFFER_TYPE_DYNAMIC_HANDLE = 0x8,
};

/**
 * @brief 枚举共享内存类型
 */
enum ShareMemTypes {
    /** 可读可写的共享内存类型 */
    READ_WRITE_TYPE = 0x1,
    /** 可读的共享内存类型 */
    READ_ONLY_TYPE = 0x2,
};

/**
 * @brief Codec buffer信息的定义
 */
struct OmxCodecBuffer {
    uint32_t bufferId;               /** buffer ID */
    uint32_t size;                   /** 结构体大小 */
    union OMX_VERSIONTYPE version;   /** 组件版本信息 */
    enum BufferType bufferType;      /** buffer类型 */
    uint8_t *buffer;                 /** 编码或者解码使用的buffer */
    uint32_t bufferLen;              /** buffer大小 */
    uint32_t allocLen;               /** 申请的buffer大小 */
    uint32_t filledLen;              /** 填充的buffer大小 */
    uint32_t offset;                 /** 有效数据从缓冲区开始的起始偏移量 */
    int32_t fenceFd;                 /** 该描述符来自buffer消费者, Codec等待成功后才可以使用输入或者输出buffer */
    enum ShareMemTypes type;         /** 共享内存类型 */
    int64_t pts;                     /** 时间戳 */
    uint32_t flag;                   /** 标志 */
};

/**
 * @brief 枚举Codec扩展index
 */
enum OmxIndexCodecExType {
    /** BufferType 扩展index */
    OMX_IndexExtBufferTypeStartUnused = OMX_IndexKhronosExtensions + 0x00a00000,
    /** SupportBuffer类型 */
    OMX_IndexParamSupportBufferType,
    /** UseBuffer类型 */
    OMX_IndexParamUseBufferType,
    /** GetBufferHandleUsage类型 */
    OMX_IndexParamGetBufferHandleUsage,
};

/**
 * @brief SupportBuffer类型定义
 */
struct SupportBufferType {
    uint32_t size;                                          /** 结构体大小 */
    union OMX_VERSIONTYPE version;                          /** 组件版本信息 */
    uint32_t portIndex;                                     /** 端口索引 */
    uint32_t bufferTypes;                                   /** 支持的所有Buffer类型 */
};

/**
 * @brief UseBuffer类型定义
 */
struct UseBufferType {
    uint32_t size;                                         /** 结构体大小 */
    union OMX_VERSIONTYPE version;                         /** 组件版本信息 */
    uint32_t portIndex;                                    /** 端口索引 */
    uint32_t bufferType;                                   /** Buffer类型 */
};

/**
 * @brief BufferHandleUsage类型定义
 */
struct GetBufferHandleUsageParams {
    uint32_t size;                                         /** 结构体大小 */
    union OMX_VERSIONTYPE version;                         /** 组件版本信息 */
    uint32_t portIndex;                                    /** 端口索引 */
    uint32_t usage;                                        /** usage */
};

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

#endif /* CODEC_COMPONENT_TYPE_H */
/** @} */